package com.g5.edu.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.g5.edu.exception.ServiceException;
import com.g5.edu.model.DfUsersInfo;
import com.g5.edu.mapper.DfUsersInfoMapper;
import com.g5.edu.model.Permission;
import com.g5.edu.model.Role;
import com.g5.edu.service.IDfUsersInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.g5.edu.vo.RegisterVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.sql.rowset.serial.SerialException;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author admin
 * @since 2021-10-29
 */
@Slf4j
@Service
public class DfUsersInfoServiceImpl extends ServiceImpl<DfUsersInfoMapper, DfUsersInfo> implements IDfUsersInfoService, UserDetailsService {

    @Autowired
    private DfUsersInfoMapper dfUsersInfoMapper;

//    /**
//     * 查询数据库中是否已经存在该邮箱注册的账号
//     * @param email
//     * @return
//     */
//    @Override
//    public boolean verify(String email) {
//        QueryWrapper<DfUsersInfo> wrapper = new QueryWrapper();
//        wrapper.eq("email",email);   // where email = "123@qq.com";
//        DfUsersInfo dfUsersInfo = dfUsersInfoMapper.selectOne(wrapper); // select * from df_users_info where email = "123@qq.com";
//        if (dfUsersInfo != null){
//           log.debug("校验不通过,邮箱已存在");
//           return false;
//        }
//       return true;
//    }

    // 下面的方法是接口提供的,我们来实现 // 方法的参数是用户在登录表单编写的用户名 // 方法的返回值是UserDetails类型,这个类型对象包含登录需要 的 // 用户名密码权限等
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 1.根据用户名查询用户对象
        DfUsersInfo user = dfUsersInfoMapper.findUserByUsername(username);
        // 2.判断是否能够查询到用户,没有该用户表示用户名不存在
        if (user == null) {
            return null;
        }
        // 3.根据用户id查询用户的所有权限

        List<Permission> permissions = dfUsersInfoMapper.findUserPermissionsById(user.getId());
        // 4.将权限的集合转换为String类型数组,并赋值
        String[] auth = new String[permissions.size()];
        int i = 0;
        log.info("权限数组为--："+permissions.toString());
        for (Permission p : permissions) {
            log.info("权限p--:"+ p.toString());
            auth[i] = p.getName();
            i++;
        }
        // 查询当前用户所有角色
        List<Role> roles=dfUsersInfoMapper.findUserRolesById(user.getId());
        // 数组扩容
        auth= Arrays.copyOf(auth, auth.length+roles.size());
        for(Role role:roles){
            auth[i++]=role.getName();
        }
        // 5.构建UserDetails对象
        UserDetails details = User.builder()
                .username(user.getUsername())
                .password(user.getPassword())
                .authorities(auth)
                .build();
        // 6.返回UserDetails对象
        log.info("用户详情--："+details);
        return details;
    }

    @Override
    public void register(RegisterVo registerVo) {
        QueryWrapper<DfUsersInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("email", registerVo.getEmail());   // where email = "123@qq.com";
        DfUsersInfo dfUsersInfo = dfUsersInfoMapper.selectOne(wrapper); // select * from df_users_info where email = "123@qq.com";
        if (dfUsersInfo != null) {
            throw new ServiceException("此邮箱已注册！");
        }
        DfUsersInfo user = dfUsersInfoMapper.findUserByUsername(registerVo.getUsername());
        if (user != null) {
            throw new ServiceException("此用户名已注册！");
        }
        PasswordEncoder encoder = new BCryptPasswordEncoder();
        String pwd = "{bcrypt}" + encoder.encode(registerVo.getPassword());
        DfUsersInfo u = new DfUsersInfo()
                .setUsername(registerVo.getUsername())
                .setPassword(pwd)
                .setEmail(registerVo.getEmail())
                .setAge(23)
                .setGender("男")
                .setCreateTime(LocalDateTime.now());
        int num = dfUsersInfoMapper.insert(u);
        if (num != 1) {
            throw new ServiceException("数据库忙");
        }


    }
}
